<template>
    <NInput v-model:value="keyword"></NInput>
    <NButton @click="search">搜索</NButton>

    <div>
        <div v-for="soft in softList"
             style="margin-bottom: 5px;border-bottom: 1px solid #eee">
            <div>
                软件名: {{ soft.name }}
            </div>
            <div>
                描述: {{ soft.desc }}
            </div>
            <div>
                下载地址: <span style="color: #1890ff">{{ soft.url }}</span>
                <NButton style="margin-left: 15px;" v-if="soft.canDownload" type="success" @click="download(soft)">下载
                </NButton>
                <div class="flex align-middle content-center" v-if="soft.downloadProgress">
                    <NProgress
                        style="max-width:75%"
                        class="flex-1 m-1"
                        type="line"
                        :percentage="Number(((soft.downloadProgress.Current / (soft.downloadProgress.Total|| 1) ) * 100).toFixed(2))"
                        :indicator-placement="'inside'"
                        :processing="soft.downloadProgress.Current !== soft.downloadProgress.Total"
                    />
                    <div class="inline m-1 align-center">{{ soft.downloadProgress.Speed }}</div>
                    <div class="inline m-1 align-center">{{ bytesToSizeWithUnit(soft.downloadProgress.Total) }}</div>
                </div>

            </div>
            <div>
                来源/渠道: {{ soft.channel }}
            </div>
        </div>

    </div>
</template>

<script lang="ts">
import {defineComponent, onMounted, reactive, ref, toRefs} from "vue";
import {Methods, request} from "frontend/src/utils/wails/request";
import {NButton, NInput, NProgress, useMessage} from "naive-ui";
import qs from "qs"
import {bytesToSizeWithUnit, convertToFileSizeWithUnit} from "frontend/src/utils/file/file";
import {Download, ProgressListener, SpeedOfProgress} from "frontend/src/utils/wails/download";
import {Dialog, Mode} from "frontend/src/utils/wails/dialog";

export type SoftSize = number

export enum SoftSizeType {
    Unknown = 0
}

export interface SoftItem {
    name: string,
    desc: string,
    url: string,
    size: SoftSize | string,
    channel?: string,
    canDownload?: boolean,
    downloadProgress?: SpeedOfProgress
}

export default defineComponent({
    name: "index",
    components: {
        NInput,
        NButton,
        NProgress
    },
    setup() {
        const message = useMessage()

        function baoKu() {
            if (!data.keyword) {
                return
            }
            let params = {
                keyword: data.keyword,
                page: 1,
                channel: "",
                callBack: ""
            }

            request({
                header: undefined,
                method: Methods.GET,
                url: `http://bapi.safe.360.cn/soft/search?${qs.stringify(params)}`
            }).then(resp => {
                console.log(resp)

                let data = resp.data.data.list || []
                data.map((item): SoftItem => {
                    let name = item.softname
                    let desc = item.desc
                    let size = item.size
                    let url = item.soft_download
                    console.log("baoKu", name, url)
                    return {
                        canDownload: !!url,
                        channel: "baoKu",
                        desc: desc,
                        name: name,
                        size: size,
                        url: url
                    }
                }).forEach(item => {
                    softList.value.push(item)
                })
            })
        }

        function qqPCMgr() {
            if (!data.keyword) {
                return
            }
            let params = {
                type: "search",
                callback: "searchCallback",
                keyword: data.keyword,
                page: 1,
                pernum: 30,
                more: 0
            }

            function getCDATA(content?: string) {
                if (!content) {
                    return ""
                }
                let reg = /\s*(.*)\s*/
                let groups = content.match(reg)
                return groups ? groups[1] || "" : ""
            }

            request({
                method: Methods.GET,
                url: `https://s.pcmgr.qq.com/tapi/web/searchcgi.php?${qs.stringify(params)}`
            }).then(resp => {
                console.log(resp)
                let reg = /searchCallback\((.*)\)/
                let data = (JSON.parse(resp.data.match(reg)![1]) || {}).list || []
                console.log(data)

                data.map((item): SoftItem => {
                    let xml = new window.DOMParser()
                    let info = xml.parseFromString(item.xmlInfo || "", "text/xml")
                    let name = getCDATA(info.getElementsByTagName("displayname")[0].textContent || "")
                    let url = getCDATA(info.getElementsByTagName("url")[0].textContent || "")
                    let desc = getCDATA(info.getElementsByTagName("feature")[0].textContent || "")
                    console.log("qqPCMgr", name, url)

                    return {
                        canDownload: true,
                        channel: "qqPCMgr",
                        desc: desc,
                        name: name,
                        size: 0,
                        url: url
                    }
                }).forEach(item => {
                    softList.value.push(item)
                })
            })
        }

        function chocolatey() {
            let params = qs.stringify({
                "includePrerelease": "false"
            })

            let url = "https://community.chocolatey.org/api/v2/Search()?"
            url += `$filter=IsLatestVersion&$skip=0&$top=30&searchTerm='${data.keyword}'&`
            url += params

            request({
                method: Methods.GET,
                url: url
            }).then(resp => {
                console.log(resp)
                let xml = new window.DOMParser()
                let data = xml.parseFromString(resp.data, "text/xml")
                console.log(data)
                let softs = Array.from(data.getElementsByTagName("entry"))
                console.log(softs)
                let softInfoArr = softs.filter(soft => {
                    return soft.getElementsByTagName("m:properties")[0]
                })

                softInfoArr.forEach(info => {
                    let title = (info.getElementsByTagName("d:Title")[0] || {}).textContent || ""
                    let desc = (info.getElementsByTagName("d:Description")[0] || {}).textContent || ""
                    let url = ((info.getElementsByTagName("d:DownloadCache")[0] || {}).textContent || "").split("|")[0]
                    url = url.split("^")[0]

                    console.log("chocolatey", title, url)

                    softList.value.push({
                        canDownload: !!url,
                        channel: "chocolatey",
                        desc: desc,
                        name: title,
                        size: SoftSizeType.Unknown,
                        url: url
                    })
                })
            })
        }

        function search() {
            softList.value = []
            chocolatey()
            qqPCMgr()
            baoKu()
        }

        function download(soft: SoftItem) {
            let msg = message.loading("请求下载信息", {duration: 0})
            request({
                method: Methods.HEAD,
                url: soft.url
            }).then(resp => {
                console.log(resp)
                let headers = resp.header
                let size = (headers["Size"] || headers["Content-Length"] || [])[0]
                console.log(headers)

                let tmp = soft.url.split("/")
                let contentDisposition = qs.parse(((headers["Content-Disposition"] || [""])[0]).split("; ").pop())
                let fileName = ((headers["Filename"] || contentDisposition["Filename"] || [""])[0] || tmp[tmp.length - 1]).replace(/["']/g, "")

                let supportSplit = headers.hasOwnProperty("Accept-Ranges")
                if (supportSplit) {
                    console.log(`[√] ${soft.url} 支持 分片 下载, 文件名: ${fileName}, 文件大小: ${size || "未知"}, ${convertToFileSizeWithUnit(size)}`)
                } else {
                    console.log(`[!] ${soft.url} 不支持 分片 下载, 文件名: ${fileName}`)
                }

                const progressListener: ProgressListener = (data) => {
                    console.log(data)
                    soft.downloadProgress = data
                    console.log(`[下载进度] 文件:${data.Name} 当前下载:${data.Current} 总大小:${data.Total} 速度:${data.Speed}`)
                }

                msg.destroy()
                Dialog(Mode.Dir, {
                    title: "文件下载至",
                }).then(path => {
                    if (!path) {
                        return
                    }
                    Download(soft.url, `${path}\\${fileName}`, progressListener).then((err) => {
                        if (!err) {
                            console.log(`文件 ${fileName} 写入完成`)
                            message.success(`${fileName} 下载完成`,{
                                duration: 1500
                            })
                        }
                    })
                })

            }).catch(e => {
                console.log(e)
                msg.destroy()
                message.error(e.message)
            })
        }

        const data = reactive({
            keyword: "",

        })

        onMounted(() => {
            search()
        })

        const softList = ref<SoftItem[]>([])

        return {
            ...toRefs(data),
            search,
            softList,
            download,
            bytesToSizeWithUnit
        }
    },
})
</script>

<style scoped>

</style>